﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Globalization;

namespace BDSim
{
    /// <summary>
    /// 星座生成MVVM开发模式中的ModelViewModel类
    /// </summary>
    public class WalkerSatConstWndViewModel : INotifyPropertyChanged
    {
        #region 属性

        #region 用户界面选中的当前的卫星轨道类型

        //卫星轨道坐标的类型列表
        List<string> _OrbitTypeList = new List<string>() { "ECI坐标速度", "ECF坐标速度", "轨道六根数" };

        public List<string> OrbitTypeList
        {
            get { return _OrbitTypeList; }
            set { _OrbitTypeList = value; }
        }

        //MEO卫星的选中的轨道类型
        OrbitDataType _MEOOrbitSelected = OrbitDataType.ECIPosVel;

        public OrbitDataType MEOOrbitSelected
        {
            get { return _MEOOrbitSelected; }
            set { _MEOOrbitSelected = value; NotifyChanged("MEOOrbitSelected"); }
        }

        #endregion

        #region 卫星的初始化时间

        //MEO卫星的初始化时间
        string _MEOInitTime = "2015:10:1:0:0:0.0";
        public string MEOInitTime
        {
            get { return _MEOInitTime; }
            set { _MEOInitTime = value; NotifyChanged("MEOInitTime"); }
        }

        #endregion

        #region 卫星轨道数据的的单位绑定源数据

        //与ComboBox绑定的长度数据源
        List<string> _LengthUnitList = new List<string>() { "m", "km" };

        public List<string> LengthUnitList
        {
            get { return _LengthUnitList; }
            set { _LengthUnitList = value; }
        }

        //与ComboBox绑定的速度数据源
        List<string> _VelUnitList = new List<string>() { "m/s", "km/s" };

        public List<string> VelUnitList
        {
            get { return _VelUnitList; }
            set { _VelUnitList = value; }
        }

        //与ComboBox绑定的角度数据源
        List<string> _AngUnitList = new List<string>() { "deg", "rad" };

        public List<string> AngUnitList
        {
            get { return _AngUnitList; }
            set { _AngUnitList = value; }
        }

        // //与ComboBox绑定的时间数据源
        List<string> _TimeUnitList = new List<string>() { "UTC", "JD", "MJD" };

        public List<string> TimeUnitList
        {
            get { return _TimeUnitList; }
            set { _TimeUnitList = value; }
        }

        //与ComboBox绑定的升交点赤经类型数据源
        List<string> _OmegaKindList = new List<string>() { "RAAN/ECI", "Lon/ECF" };

        public List<string> OmegaKindList
        {
            get { return _OmegaKindList; }
            set { _OmegaKindList = value; }
        }

        #region 与Walker星座有关的数据单位绑定属性

        //与Walker星座轨道历元单位绑定数据
        OrbitTimeUnit _WalkerOrbitTimeUnitSelect = new OrbitTimeUnit();

        public OrbitTimeUnit WalkerOrbitTimeUnitSelect
        {
            get { return _WalkerOrbitTimeUnitSelect; }
            set { _WalkerOrbitTimeUnitSelect = value; NotifyChanged("WalkerOrbitTimeUnitSelect"); }
        }

        //与Walker星座轨道轨道ECI单位绑定数据
        OrbitPVUnit _WalkerECIOrbitPVUnitSelect = new OrbitPVUnit(OrbitDataType.ECIPosVel);

        public OrbitPVUnit WalkerECIOrbitPVUnitSelect
        {
            get { return _WalkerECIOrbitPVUnitSelect; }
            set { _WalkerECIOrbitPVUnitSelect = value; NotifyChanged("WalkerECIOrbitPVUnitSelect"); }
        }

        //与Walker星座轨道六根数单位绑定数据
        OrbitElemUnit _WalkerOrbitEleUnitSelect = new OrbitElemUnit();

        public OrbitElemUnit WalkerOrbitEleUnitSelect
        {
            get { return _WalkerOrbitEleUnitSelect; }
            set { _WalkerOrbitEleUnitSelect = value; NotifyChanged("WalkerOrbitEleUnitSelect"); }
        }

        //与Walker星座轨道ECF轨道单位绑定数据
        OrbitPVUnit _WalkerECFOrbitPVUnitSelect = new OrbitPVUnit(OrbitDataType.ECFPosVel);

        public OrbitPVUnit WalkerECFOrbitPVUnitSelect
        {
            get { return _WalkerECFOrbitPVUnitSelect; }
            set { _WalkerECFOrbitPVUnitSelect = value; NotifyChanged("WalkerECFOrbitPVUnitSelect"); }
        }
        #endregion


        #region Walker星座形态数据

        //Walker星座的卫星总数
        int _WalkerSat_T = 24;

        public int WalkerSat_T
        {
            get { return _WalkerSat_T; }
            set
            {
                if (value > 0)
                {
                    _WalkerSat_T = value;
                    NotifyChanged("WalkerSat_T");
                }
                if (value % _WalkerSat_P != 0)
                {
                    MessageBox.Show("卫星总数需大于0且是轨道面数的整倍数!");
                }
            }
        }

        //Walker星座的轨道面数
        int _WalkerSat_P = 3;

        public int WalkerSat_P
        {
            get { return _WalkerSat_P; }
            set
            {
                if (value > 0 && (_WalkerSat_T % value == 0))
                {
                    _WalkerSat_P = value;
                    NotifyChanged("WalkerSat_P");
                }
                else
                {
                    MessageBox.Show("轨道面个数需大于0且能整除卫星总数!");
                }
            }
        }

        //Walker星座的相位
        int _WalkerSat_F = 1;

        public int WalkerSat_F
        {
            get { return _WalkerSat_F; }
            set
            {
                if (value >= 0 && value <= _WalkerSat_P - 1)
                {
                    _WalkerSat_F = value;
                    NotifyChanged("WalkerSat_F");
                }
                else
                {
                    MessageBox.Show("轨道相位参数需设置在[0,轨道面个数-1]之间!");
                }
            }
        }

        #endregion

        #region 卫星轨道数据绑定信息

        //MEO卫星轨道ECI坐标数据
        OrbitPosVelModel _MEOECIOrbit = new OrbitPosVelModel();

        public OrbitPosVelModel MEOECIOrbit
        {
            get { return _MEOECIOrbit; }
            set { _MEOECIOrbit = value; NotifyChanged("MEOECIOrbit"); }
        }

        //MEO卫星轨道ECF坐标数据
        OrbitPosVelModel _MEOECFOrbit = new OrbitPosVelModel();

        public OrbitPosVelModel MEOECFOrbit
        {
            get { return _MEOECFOrbit; }
            set { _MEOECFOrbit = value; NotifyChanged("MEOECFOrbit"); }
        }

        //MEO卫星轨道根数数据
        OrbitElementModel _MEOElemOrbit = new OrbitElementModel();

        public OrbitElementModel MEOElemOrbit
        {
            get { return _MEOElemOrbit; }
            set { _MEOElemOrbit = value; NotifyChanged("MEOElemOrbit"); }
        }

        #endregion

        #endregion

        #endregion

        #region 方法

        #region 私有方法

        /// <summary>
        /// 从界面获得卫星坐标速度在默认单位下的数据
        /// 数据的默认格式问题：
        /// 长度单位：m
        /// 时间单位：UTC
        /// 角度单位：deg
        /// 升交点赤经形式：RAAN/ECI
        /// </summary>
        /// <param name="data">轨道坐标数据</param>
        /// <param name="unit">相应数据的单位</param>
        /// <returns></returns>
        NodePosVel GetOrbitPVFromUI(OrbitPosVelModel data, DataUnit unit)
        {
            NodePosVel pv = new NodePosVel();

            if (unit.DataType == OrbitDataType.ECIPosVel || unit.DataType == OrbitDataType.ECFPosVel)
            {
                switch (((OrbitPVUnit)unit).XUnit)
                {
                    case "m":
                        pv.x = data.X;
                        break;
                    case "km":
                        pv.x = data.X * 1000;
                        break;
                }
                switch (((OrbitPVUnit)unit).YUnit)
                {
                    case "m":
                        pv.y = data.Y;
                        break;
                    case "km":
                        pv.y = data.Y * 1000;
                        break;
                }
                switch (((OrbitPVUnit)unit).ZUnit)
                {
                    case "m":
                        pv.z = data.Z;
                        break;
                    case "km":
                        pv.z = data.Z * 1000;
                        break;
                }
                switch (((OrbitPVUnit)unit).VXUnit)
                {
                    case "m/s":
                        pv.vx = data.VX;
                        break;
                    case "km/s":
                        pv.vx = data.VX * 1000;
                        break;
                }
                switch (((OrbitPVUnit)unit).VYUnit)
                {
                    case "m/s":
                        pv.vy = data.VY;
                        break;
                    case "km/s":
                        pv.vy = data.VY * 1000;
                        break;
                }
                switch (((OrbitPVUnit)unit).VZUnit)
                {
                    case "m/s":
                        pv.vz = data.VZ;
                        break;
                    case "km/s":
                        pv.vz = data.VZ * 1000;
                        break;
                }
            }
            return pv;

        }

        /// <summary>
        /// 从界面获得卫星轨道根数在默认单位下的数据
        /// 数据的默认格式问题：
        /// 长度单位：m
        /// 时间单位：UTC
        /// 角度单位：deg
        /// 升交点赤经形式：RAAN/ECI
        /// </summary>
        /// <param name="data">轨道根数数据</param>
        /// <param name="unit">数据相应单位</param>
        /// <param name="JD">UTC的儒略日</param>
        /// <returns></returns>
        Orbit6Element GetOrbitElemFromUI(OrbitElementModel data, DataUnit unit, double JD)
        {
            Orbit6Element elem = new Orbit6Element();
            elem.epoch.JD = JD;
            TimeSpaceDll.CAL2UTC(out elem.epoch, 2);
            double Rad2Deg = 180.0 / Math.PI;
            if (unit.DataType == OrbitDataType.Element)
            {
                switch (((OrbitElemUnit)unit).AUnit)
                {
                    case "m":
                        elem.a = data.A;
                        break;
                    case "km":
                        elem.a = data.A * 1000;
                        break;
                    default:
                        break;
                }
                elem.e = data.E;
                switch (((OrbitElemUnit)unit).IUnit)
                {
                    case "deg":
                        elem.i = data.I;
                        break;
                    case "rad":
                        elem.i = data.I * Rad2Deg;
                        break;
                    default:
                        break;
                }
                switch (((OrbitElemUnit)unit).FUnit)
                {
                    case "deg":
                        elem.f = data.F;
                        break;
                    case "rad":
                        elem.f = data.F * Rad2Deg;
                        break;
                }
                switch (((OrbitElemUnit)unit).OmegaKind)//默认的升交点赤经数据是ECI的RAAN,默认的角度单位是deg
                {
                    case "RAAN/ECI":
                        switch (((OrbitElemUnit)unit).OmegaUnit)
                        {
                            case "deg":
                                elem.O = data.O;
                                break;
                            case "rad":
                                elem.O = data.O * Rad2Deg;
                                break;
                        }
                        break;
                    case "Lon/ECF":
                        switch (((OrbitElemUnit)unit).OmegaUnit)
                        {
                            case "deg":
                                elem.O = data.O;
                                break;
                            case "rad":
                                elem.O = data.O * Rad2Deg;
                                break;
                        }
                        break;

                }
                switch (((OrbitElemUnit)unit).WUnit)
                {
                    case "deg":
                        elem.w = data.W;
                        break;
                    case "rad":
                        elem.w = data.W * Rad2Deg;
                        break;
                }
            }
            return elem;
        }

        /// <summary>
        /// 从界面获得卫星轨道历元在默认单位下的数据
        /// 数据的默认格式问题：
        /// 长度单位：m
        /// 时间单位：UTC
        /// 角度单位：deg
        /// 升交点赤经形式：RAAN/ECI
        /// </summary>
        /// <param name="data">轨道历元字符串/param>
        /// <param name="unit">数据相应单位</param>
        /// <returns></returns>
        UTCTime GetOrbitTimeFromUI(string data, DataUnit unit)
        {
            UTCTime epoh = new UTCTime();
            if (unit.DataType == OrbitDataType.Time)
            {
                switch (((OrbitTimeUnit)unit).Epoh)
                {
                    case "UTC":
                        string[] time = data.Split(':', '-', ' ');
                        if (time.Length == 6)
                        {
                            epoh.Year = Convert.ToInt32(time[0]);
                            epoh.mon = Convert.ToInt32(time[1]);
                            epoh.day = Convert.ToInt32(time[2]);
                            epoh.Hour = Convert.ToInt32(time[3]);
                            epoh.Min = Convert.ToInt32(time[4]);
                            epoh.sec = Convert.ToDouble(time[5]);
                            TimeSpaceDll.CAL2UTC(out epoh, 1);//UTC转JD
                        }
                        break;
                    case "JD":
                        epoh.Jd = Convert.ToDouble(data);
                        TimeSpaceDll.CAL2UTC(out epoh, 2);//JD转UTC
                        break;
                    case "MJD":
                        break;
                    default:
                        break;
                }
            }

            return epoh;
        }



        #endregion

        #region 公有方法

        /// <summary>
        /// 从界面获取轨道坐标速度数据，考虑到不同单位
        /// </summary>
        /// <param name="SatType">卫星类型："MEO","IGSO","GEO"</param>
        /// <param name="DataType">数据类型</param>
        /// <returns></returns>
        public NodePosVel GetOrbitPVTFromUI(string SatType, OrbitDataType DataType)
        {
            NodePosVel pv = new NodePosVel();
            pv.Epoch = GetOrbitTimeFromUI("SatType");
            switch (SatType)
            {
                case "MEO":
                    switch (DataType)
                    {
                        case OrbitDataType.ECIPosVel:
                            pv = GetOrbitPVFromUI(MEOECIOrbit, WalkerECIOrbitPVUnitSelect);
                            break;
                        case OrbitDataType.ECFPosVel:
                            pv = GetOrbitPVFromUI(MEOECFOrbit, WalkerECFOrbitPVUnitSelect);
                            break;
                        default:
                            break;
                    }
                    break;

                default:
                    break;
            }
            return pv;
        }

        /// <summary>
        /// 从界面获取轨道六根数数据，考虑到不同单位
        /// </summary>
        /// <param name="SatType">卫星类型："MEO","IGSO","GEO"</param>
        /// <param name="DataType">数据类型</param>
        /// <returns></returns>
        public Orbit6Element GetOrbitElemTFromUI(string SatType, OrbitDataType DataType)
        {
            Orbit6Element elem = new Orbit6Element();
            elem.epoch = GetOrbitTimeFromUI(SatType);
            switch (SatType)
            {
                case "MEO":
                    if (DataType == OrbitDataType.Element)
                    {
                        elem = GetOrbitElemFromUI(MEOElemOrbit, WalkerOrbitEleUnitSelect, elem.epoch.JD);
                    }
                    break;
                default:
                    break;
            }

            return elem;
        }

        /// <summary>
        ///  从界面获取轨道历元信息
        /// </summary>
        /// <param name="SatType">卫星类型："MEO","IGSO","GEO"</param>
        /// <param name="DataType">数据类型</param>
        /// <returns></returns>
        public UTCTime GetOrbitTimeFromUI(string SatType)
        {
            UTCTime epoh = new UTCTime();
            switch (SatType)
            {
                case "MEO":
                    epoh = GetOrbitTimeFromUI(MEOInitTime, WalkerOrbitTimeUnitSelect);

                    break;
                default:
                    break;
            }

            return epoh;
        }

        /// <summary>
        /// 轨道数据初始化，主要用于ECI,ECF,Elem三中轨道数据的同步
        /// </summary>
        public void InitOrbit(NodePosVel ECIpv)
        {
            UTCTime systime = ECIpv.Epoch;
            MEOInitTime = systime.ToString();

            NodePosVel ECFpv = new NodePosVel();
            Orbit6Element elem = new Orbit6Element();

            MEOECIOrbit.X = ECIpv.X;
            MEOECIOrbit.Y = ECIpv.Y;
            MEOECIOrbit.Z = ECIpv.Z;
            MEOECIOrbit.VX = ECIpv.VX;
            MEOECIOrbit.VY = ECIpv.VY;
            MEOECIOrbit.VZ = ECIpv.VZ;

            //ECI转ECF
            TimeSpaceDll.ECI2ECF(ECIpv, 0, 0, out ECFpv);
            MEOECFOrbit.X = ECFpv.X;
            MEOECFOrbit.Y = ECFpv.Y;
            MEOECFOrbit.Z = ECFpv.Z;
            MEOECFOrbit.VX = ECFpv.VX;
            MEOECFOrbit.VY = ECFpv.VY;
            MEOECFOrbit.VZ = ECFpv.VZ;

            //ECI转Elem
            TimeSpaceDll.ECI2Element(ECIpv, out elem);
            MEOElemOrbit.A = elem.a;
            MEOElemOrbit.E = elem.e;
            MEOElemOrbit.F = elem.f;
            MEOElemOrbit.I = elem.i;
            MEOElemOrbit.O = elem.O;
            MEOElemOrbit.W = elem.w;
        }

        /// <summary>
        /// 升交点经度与赤经的变换，flag=1：RAAN->Lon,flag=2:Lon->RAAN
        /// 特别注意：data中数据单位为m和rad,data中的历元信息必须有
        /// </summary>
        /// <param name="data"></param>
        /// <param name="epoh"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        public double RAAN2Lon(Orbit6Element data, int flag)
        {
            double ret = 0;
            if (flag == 1)//RAAN->Lon
            {
                ret = WalkerSatConstWnd.RAAN2Lon(data.f, data.O, data.a, data.epoch.Jd);
            }
            else if (flag == 2)//Lon->RAAN
            {
                ret = WalkerSatConstWnd.Lon2RAAN(data.f, data.O, data.a, data.epoch.Jd);//注：此函数的正确性有待验证
            }
            return ret;
        }

        /// <summary>
        /// 升交点经度与赤经的变换，flag=1：RAAN->Lon,flag=2:Lon->RAAN
        /// </summary>
        /// <param name="SatType">卫星类型</param>
        /// <param name="flag">flag=1：RAAN->Lon,flag=2:Lon->RAAN</param>
        /// <returns></returns>
        public double RAAN2Lon(string SatType, int flag)
        {
            double ret = 0;
            double Deg2Rad = Math.PI / 180.0;
            if (flag == 1)
            {
                switch (SatType)
                {
                    case "MEO":
                        //获得界面数据                     
                        Orbit6Element MEOelem = GetOrbitElemTFromUI("MEO", OrbitDataType.Element);
                        MEOelem.i *= Deg2Rad;
                        MEOelem.O *= Deg2Rad;
                        MEOelem.w *= Deg2Rad;
                        MEOelem.f *= Deg2Rad;
                        ret = RAAN2Lon(MEOelem, 1);
                        break;
                    default:
                        break;
                }
            }
            else if (flag == 2)
            {
                switch (SatType)
                {
                    case "MEO":
                        //获得界面数据                     
                        Orbit6Element MEOelem = GetOrbitElemTFromUI("MEO", OrbitDataType.Element);
                        MEOelem.i *= Deg2Rad;
                        MEOelem.O *= Deg2Rad;
                        MEOelem.w *= Deg2Rad;
                        MEOelem.f *= Deg2Rad;
                        ret = RAAN2Lon(MEOelem, 2);
                        break;
                    default:
                        break;
                }

            }
            return ret;
        }

        #endregion

        #endregion

        #region 属性值更改通知事件
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
        #endregion

        SimpleCommand _MEOECIComboSelectChanged = new SimpleCommand();
        public SimpleCommand MEOECIComboSelectChanged
        {
            get { return _MEOECIComboSelectChanged; }
            set { _MEOECIComboSelectChanged = value; NotifyChanged("MEOECIComboSelectChanged"); }
        }

        private void MEOECIComboSelectChanged_Execute(object o)
        {

        }
    }


    #region 星座生成MVVM开发模式中的Model

    /// <summary>
    /// 轨道数据类型枚举
    /// </summary>
    public enum OrbitDataType
    {
        ECIPosVel,
        ECFPosVel,
        Element,
        BLH,
        Time
    }

    /// <summary>
    /// 一组数据数据所组成实体的数据单位基类
    /// </summary>
    public class DataUnit
    {
        OrbitDataType _DataType = new OrbitDataType();

        public OrbitDataType DataType
        {
            get { return _DataType; }
            set { _DataType = value; }
        }

    }
    /// <summary>
    /// 卫星轨道位置速度的单位
    /// </summary>
    public class OrbitPVUnit : DataUnit, INotifyPropertyChanged
    {

        //X单位
        string _XUnit = "m";

        public string XUnit
        {
            get { return _XUnit; }
            set { _XUnit = value; NotifyChanged("XUnit"); }
        }

        //Y单位
        string _YUnit = "m";

        public string YUnit
        {
            get { return _YUnit; }
            set { _YUnit = value; NotifyChanged("YUnit"); }
        }

        //Z单位
        string _ZUnit = "m";

        public string ZUnit
        {
            get { return _ZUnit; }
            set { _ZUnit = value; NotifyChanged("ZUnit"); }
        }

        //VX单位
        string _VXUnit = "m/s";

        public string VXUnit
        {
            get { return _VXUnit; }
            set { _VXUnit = value; NotifyChanged("VXUnit"); }
        }


        //VY单位
        string _VYUnit = "m/s";

        public string VYUnit
        {
            get { return _VYUnit; }
            set { _VYUnit = value; NotifyChanged("VYUnit"); }
        }

        //VZ单位
        string _VZUnit = "m/s";

        public string VZUnit
        {
            get { return _VZUnit; }
            set { _VZUnit = value; NotifyChanged("VZUnit"); }
        }

        //构造函数
        public OrbitPVUnit(OrbitDataType datatype)
        {
            DataType = datatype;
        }

        //属性值改变通知时间
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 属性值改变通知函数
        /// </summary>
        /// <param name="PropertyName">属性名</param>
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
    /// <summary>
    /// 卫星轨道六根数的数据单位
    /// </summary>
    public class OrbitElemUnit : DataUnit, INotifyPropertyChanged
    {

        string _aUnit = "m";

        public string AUnit
        {
            get { return _aUnit; }
            set { _aUnit = value; NotifyChanged("AUnit"); }
        }
        string _iUnit = "deg";

        public string IUnit
        {
            get { return _iUnit; }
            set { _iUnit = value; NotifyChanged("IUnit"); }
        }

        string _OmegaUnit = "deg";

        public string OmegaUnit
        {
            get { return _OmegaUnit; }
            set { _OmegaUnit = value; NotifyChanged("OmegaUnit"); }
        }
        string _OmegaKind = "RAAN/ECI";

        public string OmegaKind
        {
            get { return _OmegaKind; }
            set { _OmegaKind = value; NotifyChanged("OmegaKind"); }
        }

        string _wUnit = "deg";

        public string WUnit
        {
            get { return _wUnit; }
            set { _wUnit = value; NotifyChanged("WUnit"); }
        }
        string _fUnit = "deg";

        public string FUnit
        {
            get { return _fUnit; }
            set { _fUnit = value; NotifyChanged("FUnit"); }
        }
        //构造
        public OrbitElemUnit()
        {
            DataType = OrbitDataType.Element;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }

    /// <summary>
    /// 卫星轨道历元的数据单位
    /// </summary>
    public class OrbitTimeUnit : DataUnit, INotifyPropertyChanged
    {
        string _Epoh = "UTC";

        public string Epoh
        {
            get { return _Epoh; }
            set { _Epoh = value; NotifyChanged("Epoh"); }
        }

        public OrbitTimeUnit()
        {
            DataType = OrbitDataType.Time;
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }

    /// <summary>
    /// 卫星轨道坐标模型抽象
    /// </summary>
    public class OrbitPosVelModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

        double _X;

        public double X
        {
            get { return _X; }
            set { _X = value; NotifyChanged("X"); }
        }
        double _Y;

        public double Y
        {
            get { return _Y; }
            set { _Y = value; NotifyChanged("Y"); }
        }
        double _Z;

        public double Z
        {
            get { return _Z; }
            set { _Z = value; NotifyChanged("Z"); }
        }
        double _VX;

        public double VX
        {
            get { return _VX; }
            set { _VX = value; NotifyChanged("VX"); }
        }

        double _VY;

        public double VY
        {
            get { return _VY; }
            set { _VY = value; NotifyChanged("VY"); }
        }

        double _VZ;

        public double VZ
        {
            get { return _VZ; }
            set { _VZ = value; NotifyChanged("VZ"); }
        }

    }

    /// <summary>
    /// 卫星六根数模型抽象
    /// </summary>
    public class OrbitElementModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

        double _a;

        public double A
        {
            get { return _a; }
            set { _a = value; NotifyChanged("A"); }
        }

        double _e;

        public double E
        {
            get { return _e; }
            set { _e = value; NotifyChanged("E"); }
        }

        double _i;

        public double I
        {
            get { return _i; }
            set { _i = value; NotifyChanged("I"); }
        }

        double _o;

        public double O
        {
            get { return _o; }
            set { _o = value; NotifyChanged("O"); }
        }

        double w;

        public double W
        {
            get { return w; }
            set { w = value; NotifyChanged("W"); }
        }

        double f;

        public double F
        {
            get { return f; }
            set { f = value; NotifyChanged("F"); }
        }

    }

    #endregion


    #region 数据类型转换接口的实现类

    public class ECIOrbitDataTypeToVisibility : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Visibility vi = Visibility.Collapsed;
            if ((OrbitDataType)value == OrbitDataType.ECIPosVel)
            {
                vi = Visibility.Visible;
            }

            return vi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ECFOrbitDataTypeToVisibility : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Visibility vi = Visibility.Collapsed;
            if ((OrbitDataType)value == OrbitDataType.ECFPosVel)
            {
                vi = Visibility.Visible;
            }

            return vi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ELemOrbitDataTypeToVisibility : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Visibility vi = Visibility.Collapsed;
            if ((OrbitDataType)value == OrbitDataType.Element)
            {
                vi = Visibility.Visible;
            }

            return vi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class OrbitTypeStringToOrbitTypeEnum : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string type = "";
            switch ((OrbitDataType)value)
            {
                case OrbitDataType.ECIPosVel:
                    type = "ECI坐标速度";
                    break;
                case OrbitDataType.ECFPosVel:
                    type = "ECF坐标速度";
                    break;
                case OrbitDataType.Element:
                    type = "轨道六根数";
                    break;
                default:
                    break;
            }
            return type;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            OrbitDataType type = new OrbitDataType();
            switch ((string)value)
            {
                case "ECI坐标速度":
                    type = OrbitDataType.ECIPosVel;
                    break;
                case "ECF坐标速度":
                    type = OrbitDataType.ECFPosVel;
                    break;
                case "轨道六根数":
                    type = OrbitDataType.Element;
                    break;
                default:
                    break;
            }
            return type;
        }
    }

    #endregion
}
